<?php

namespace app\service;

use app\model\Post as PostModel;
use app\model\Catalog as CatalogModel;
use app\service\BookType as BookTypeService;
use app\model\BookType as BookTypeModel;
use support\ErrorCode;
use support\Tree;
use support\UCenterService;
use teamones\filter\Enforcer;
use think\Exception;

class Post
{

    public $member;
    public $memberPerService;
    public $BookTypeService;

    public function __construct()
    {
        $this->member = new Member();
        $this->memberPerService = new MemberPer();
        $this->BookTypeService = new BookTypeService();

    }

    /**
     * 创建文件
     * @param $data
     * @return PostModel|\think\Model|void
     * @throws \exception
     */
    public function create($data)
    {
        if (empty($data["catalog_id"])) {
            $data["catalog_id"] = 0;
        }

        if (!isset($data['number'])) {
            $data['number'] = PostModel::where(["catalog_id" => $data["catalog_id"]])->max("number") + 1;
        }
        return PostModel::create($data);
    }

    /**
     * 更新目录
     * @param $data
     * @return PostModel
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function update($data)
    {

        if (!isset($data['number'])) {
            if (isset($data['catalog_id'])) {
                $catalogId = PostModel::where(['id' => $data['id']])->value('catalog_id');
                if ($data['catalog_id'] != $catalogId) {
                    $data['number'] = PostModel::where(["catalog_id" => $data["catalog_id"]])->max("number") + 1;
                }
            }
        }
        $postModel = PostModel::where(['id' => $data['id']])->find();
        if ($postModel->save($data)) {
            // 更新知识库时间
            $this->BookTypeService->updateTime($postModel['book_type_id']);
            return $postModel;
        }
    }

    /**
     * @param $data
     * @return bool
     * @throws \Throwable
     * @throws \think\db\exception\DbException
     */
    public function delete($data)
    {
        return PostModel::where(['id' => $data['id']])->delete();
    }

    /**
     * @param $filter
     * @return \think\Collection
     * @throws \exception
     */
    public function select($filter)
    {
        return PostModel::where(Enforcer::parseWhere($filter))->select();
    }


    /**
     * 查询单条
     * @param $data
     * @param $filter
     * @return array|PostModel|string|\think\Model|null
     * @throws \exception
     */
    public function find($data, $filter)
    {
        $initFilter = $filter;
        unset($filter['tenant_id']);

        $postData = PostModel::where(Enforcer::parseWhere($filter))->find();
        if (empty($postData)) {
            return '';
        }
        $memberService = new Member();
        $platformRole = 'viewer';
        $userRoleInfo = UCenterService::getInstance()->user->request('POST', 'user/get_my_user_info', [], []);
        $departmentInfo = array_column($userRoleInfo['department_info'], 'role_code');
        if (array_intersect(['super_admin', 'operators'], $departmentInfo)) {
            $platformRole = 'super_admin';
        }
        $memberData = $memberService->getTenantInfo($initFilter['tenant_id'], 'id,created_by');
        $param['user_id'] = $data['user_id'];
        $param['tenant_id'] = $initFilter['tenant_id'];
        $param['book_type_id'] = $postData['book_type_id'];
        $param['tenantCreateById'] = $memberData['data']['created_by'] ?? 0;
        $role = 'viewer';
        if (!empty($postData['book_type_id'])) {
            $bookType = BookTypeModel::where(['id' => $postData['book_type_id']])->find();
            if (!empty($bookType)) {
                // 如果是不是平台级,则查具体分配的权限
                if ($bookType['type'] != BookTypeModel::PLATFORM_BOOK_TYPE) {
                    $role = $memberService->getNowUserPer('book', $postData['id'], $param);
                }
                // 如果是平台级知识库,则取当前用户在系统里的权限
                if ($bookType['type'] == BookTypeModel::PLATFORM_BOOK_TYPE) {
                    $role = $platformRole;
                }
            }
        }
        $postData['role'] = $role;
        return $postData;
    }


    /**
     * 创建知识本内容页
     * @param $data
     * @return CatalogModel|\think\Model
     * @throws \Throwable
     */
    public function createKnowledgeBookPage($data)
    {
        $postData = $data;
        $catalogModel = new CatalogModel();
        $data['number'] = $data['number'] ?? CatalogModel::where(["parent_id" => $data["parent_id"]])->max("number") + 1;

        if ($data["parent_id"] === 0) {
            $data['level'] = 1;
        } else {
            $data['level'] = CatalogModel::where("parent_id", $data["parent_id"])->value('level') + 1;
        }


        $catalogModel->startTrans();
        try {
            $catalog = CatalogModel::create($data);
            if (!empty($catalog)) {
                $postData['catalog_id'] = $catalog['id'];
                $postData['item_id'] = $catalog['item_id'];
                $postData['name'] = $catalog['name'];
                $postData['type'] = 'catalog_post';
                PostModel::create($postData);
            }
            $catalogModel->commit();
            return $catalog;
        } catch (\Throwable $e) {
            $catalogModel->rollback();
            throw $e;
        }
    }

    /**
     * 修改知识本内容页
     * @param $data
     * @return CatalogModel
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function updateKnowledgeBookPage($data)
    {
        $catalogModel = new CatalogModel();
        $catalog = $catalogModel->find($data['id']);
        if (empty($catalog)) {
            return null;
        }
        $catalogModel->startTrans();
        try {
            if (!empty($data['parent_id']) && $catalog['parent_id'] !== $data['parent_id']) {
                $data['number'] = $catalogModel->where('parent_id', $data['parent_id'])->max('number') + 1;
                $data['level'] = $catalogModel->where("parent_id", $data["parent_id"])->value('level') + 1;
            }

            $count = CatalogModel::update($data, ['id' => $catalog['id']]);

            $postData = [];
            if (!empty($data['item_id'])) { //项目
                $postData['item_id'] = $data['item_id'];
            }
            if (isset($data['content'])) {//内容
                $postData['content'] = $data['content'];
            }
            if (!empty($data['name'])) {//名字
                $postData['name'] = $data['name'];
            }
            if (isset($data['comments'])) { //描述
                $postData['comments'] = $data['comments'];
            }
            if (!empty($data['type'])) {
                $postData['type'] = $data['type'];
            }

            PostModel::where(['catalog_id' => $catalog['id']])->save($postData);
            $catalogModel->commit();
            return $count;
        } catch (\Throwable $e) {
            $catalogModel->rollback();
            throw $e;
        }
    }

    /**
     * 知识本树查询
     * @param $filer
     * @return array|false
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function knowledgeBookPageTree($filer)
    {
        $itemId = $filer['item_id'];
        $catalogList = CatalogModel::where(['item_id' => $itemId])->order(['number' => 'desc'])->select()->toArray();
        $catalogListIds = array_column($catalogList, 'id');
        $catalogPost = PostModel::whereIn('catalog_id', $catalogListIds)->where('type', 'catalog_post')->field('id,name,item_id,catalog_id')->select()->toArray();
        $catalogPost = array_column($catalogPost, null, 'catalog_id');
        $normalPost = PostModel::whereIn('catalog_id', $catalogListIds)->where('type', 'normal')->field('id,name,item_id,catalog_id')->select()->toArray();
        $normalPost = array_map(function ($normalPostItem) {
            $normalPostItem['is_post'] = 'yes';
            return $normalPostItem;
        }, $normalPost);
        $normalPost = array_group_by($normalPost, 'catalog_id');
        $result = [];
        if (!empty($catalogList)) {
            $t = new Tree("id", "parent_id", "catalog");
            $t->load($catalogList);
            $catalogTree = $t->DeepTree();
            $t->traverseTree($catalogTree, function (&$catalogTreeItem) use (&$catalogPost, $normalPost) {
                if (array_key_exists($catalogTreeItem['id'], $catalogPost)) {
                    $catalogTreeItem['link_post_id'] = $catalogPost[$catalogTreeItem['id']]['id'];
                }
                if (array_key_exists($catalogTreeItem['id'], $normalPost)) {
                    $catalogTreeItem['catalog'] = $normalPost[$catalogTreeItem['id']];
                }

            });
            $result = $catalogTree;
        }
        return $result;
    }

    /**
     * 删除知识页内容
     * @param $filer
     * @return bool|int
     * @throws \Throwable
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function deleteKnowledgeBookPage($filer)
    {
        $catalogModel = new CatalogModel();
        $catalogList = $catalogModel->where(Enforcer::parseWhere($filer))->field('id')->select()->toArray();
        $catalogArray = $catalogModel->select()->toArray();
        $deleteId = [];
        if (!empty($catalogArray)) {
            $catalogList = array_column($catalogList, 'id');
            $t = new Tree("id", "parent_id", "resource");
            $t->load($catalogArray);
            foreach ($catalogList as $catalogListIds) {
                $catalogSub = $t->DeepTree($catalogListIds);
                $deleteId[] = $catalogListIds;
                if (!empty($catalogSub)) {
                    $t->traverseTree($catalogSub, function ($item) use (&$deleteId) {
                        if (!array_key_exists($item["id"], $deleteId)) {
                            $deleteId[] = $item["id"];
                        }
                    });
                }
            }
        }


        $count = false;
        if (!empty($deleteId)) {
            $catalogModel->startTrans();
            try {
                $count = $catalogModel->whereIn('id', $deleteId)->delete();
                PostModel::whereIn('catalog_id', $deleteId)->delete();
                $catalogModel->commit();
            } catch (\Throwable $e) {
                $catalogModel->rollback();
                throw $e;
            }
        }
        return $count;
    }

    /**
     * 获取知识库内容树
     * @param $param
     * @return array|false|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getKnowledgeBookTree($param)
    {

        // 默认所有目录所有数据的访问权限
        $bookType = BookTypeModel::where(['id' => $param['book_type_id']])->field('type')->find();

        if (!$bookType->isEmpty()) {
            $bookType = $bookType->toArray();
        }
        if (empty($bookType)) {
            return [];
        }
        $where = ['book_type_id' => $param['book_type_id']];
        if ($bookType['type'] != BookTypeModel::PLATFORM_BOOK_TYPE) {
            $where = ['book_type_id' => $param['book_type_id'], 'tenant_id' => $param['tenant_id']];
        }
        $postModel = PostModel::where($where)->field('id,name,parent_id,number,file_type,level,created_by,last_update_time')->select();
        if (!$postModel->isEmpty()) {
            $postData = $postModel->toArray();
            $t = new Tree("id", "parent_id", "catalog");
            $t->load($postData);
            return $t->DeepTree();
        }
    }

    /**
     * 创建知识库内容树
     * @param $data
     * @return PostModel|\think\Model
     * @throws Exception
     */
    public function createKnowledgeBookTree($data)
    {
        if ($data["parent_id"] != 0) {
            $fileType = PostModel::where("id", $data["parent_id"])->value('file_type');
            if (empty($fileType)) {
                throw new Exception('File type is null', ErrorCode::CREATE_FILE_FAILURE);
            }
            // 目录下可以创建目录、文件
            $needFile = [PostModel::FILE_WORD, PostModel::FILE_EXCEL, PostModel::FILE_DIR, PostModel::FILE_DRAW];
            if ($fileType == PostModel::FILE_DIR && !in_array($data['file_type'], $needFile)) {
                throw new Exception('Unable to create directory under file', ErrorCode::CREATE_DIRECTORY_TO_FILE_FAILURE);
            }
            // 文件下可以创建文件,不可以创建文件以外的数据
            if ($fileType != PostModel::FILE_DIR && !in_array($data['file_type'], [PostModel::FILE_WORD, PostModel::FILE_EXCEL, PostModel::FILE_DRAW])) {
                throw new Exception('Unable to create directory under file', ErrorCode::CREATE_DIRECTORY_TO_FILE_FAILURE);
            }
        }
        if (empty($data["parent_id"])) {
            $data["parent_id"] = 0;
        }

        if (!isset($data['number'])) {
            $data['number'] = PostModel::where(["parent_id" => $data["parent_id"]])->max("number") + 1;
        }

        if ($data["parent_id"] === 0) {
            $data['level'] = 1;
        } else {
            $data['level'] = PostModel::where("id", $data["parent_id"])->value('level') + 1;
            if ($data['level'] > 4) {
                throw new Exception('Create a maximum of three layers of directory structures', ErrorCode::CREATE_FILE_MAXIUM_LAYERS_FAILURE);
            }
        }
        $data = PostModel::create($data);
        if (!empty($data)) {
            // 更新知识库时间
            $this->BookTypeService->updateTime($data['book_type_id']);
        }
        return $data;
    }


    /**
     * 更新知识库内容树排序
     * @param $data
     * @return PostModel
     * @throws Exception
     */
    public function updateKnowledgeBookTree($data)
    {
        if (isset($data["parent_id"])) {
            if ($data["parent_id"] != 0) {
                $fileType = PostModel::where("id", $data["id"])->value('file_type');
                $updateFileType = PostModel::where("id", $data["parent_id"])->value('file_type');
                if (empty($fileType) || empty($updateFileType)) {
                    throw new Exception('File type is null', ErrorCode::CREATE_FILE_FAILURE);
                }
                // 目录可以移动到目录下,不可以移动到文件下
                if ($fileType == PostModel::FILE_DIR && $updateFileType != PostModel::FILE_DIR) {
                    throw new Exception('Unable to update directory under file', ErrorCode::UPDATE_DIRECTORY_TO_FILE_FAILURE);
                }
                // 文件可以移动到文件、目录下
                $needFileType = [PostModel::FILE_WORD, PostModel::FILE_EXCEL, PostModel::FILE_DIR, PostModel::FILE_DRAW];
                if ($fileType != PostModel::FILE_DIR && !in_array($updateFileType, $needFileType)) {
                    throw new Exception('Unable to update directory under file', ErrorCode::UPDATE_DIRECTORY_TO_FILE_FAILURE);
                }
            }
            if ($data["parent_id"] === 0) {
                $data['level'] = 1;
            } else {
                $data['level'] = PostModel::where("id", $data["parent_id"])->value('level') + 1;
                if ($data['level'] > 4) {
                    throw new Exception('Update a maximum of three layers of directory structures', ErrorCode::UPDATE_FILE_MAXIUM_LAYERS_FAILURE);
                }
            }
            if (!isset($data['number'])) {
                $data['number'] = PostModel::where(["parent_id" => $data["parent_id"]])->max("number") + 1;
            }
        }
        return PostModel::update($data, ['id' => $data['id']]);
    }

    /**
     * 删除知识库内容树
     * @param $data
     * @return array|bool
     * @throws Exception
     * @throws \Throwable
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function deleteKnowledgeBookTree($data)
    {
        $bookTypeId = PostModel::field('book_type_id')->where(['id' => $data['id']])->find();
        if (empty($bookTypeId)) {
            throw new Exception('id not find', ErrorCode::DELETE_KNOWLEDGE_BOOK_TREE_ID_NOT_FIND);
        }
        $postArray = PostModel::field('id,parent_id')
            ->where(['tenant_id' => $data['tenant_id'], 'book_type_id' => $bookTypeId['book_type_id']])
            ->select();
        if (empty($postArray)) {
            throw new Exception('post is null', ErrorCode::DELETE_KNOWLEDGE_BOOK_POST_IS_NULL);
        }
        $postArray = $postArray->toArray();
        $t = new Tree("id", "parent_id", "children");
        $t->load($postArray);
        $postSub = $t->DeepTree($data['id']);
        $deleteId[] = $data['id'];
        if (!empty($postSub)) {
            $t->traverseTree($postSub, function ($item) use (&$deleteId) {
                $deleteId[] = $item["id"];
            });
        }
        if (!empty($deleteId)) {
            return PostModel::where(['id' => $deleteId])->delete();
        }
        return [];
    }
}
